package com.ruoyi.service.jpjs.costsummary.impl;

import com.ruoyi.common.config.Global;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.mapper.SysParameterMapper;
import com.ruoyi.mapper.jpjs.costcode.CostCodeMapper;
import com.ruoyi.mapper.jpjs.costsummary.CostSummaryMapper;
import com.ruoyi.mapper.jpjs.param.ParamMapper;
import com.ruoyi.mapper.jpjs.project.ProjectMapper;
import com.ruoyi.service.jpjs.costsummary.CostSummaryService;
import com.ruoyi.util.ExcelUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.beans.Transient;
import java.io.FileOutputStream;
import java.util.*;


@Service
public class CostSummaryServiceImpl implements CostSummaryService {

    @Autowired
    private CostSummaryMapper costSummaryMapper;

    @Autowired
    private ParamMapper paramMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private SysParameterMapper sysParameterMapper;

    @Autowired
    private CostCodeMapper costCodeMapper;

    @Override
    public List<Map<String, Object>> findCostSummaryAll(Map<String, Object> map) {
        return costSummaryMapper.findCostSummaryAll(map);
    }

    @Override
    public List<Map<String, Object>> findCostSummaryMonthAll(Map<String, Object> map) {
        return costSummaryMapper.findCostSummaryMonthAll(map);
    }

    @Override
    @Transactional
    public int saveCostSummary(List<Map<String, Object>> list) {
        List<Map<String, Object>> addList = new ArrayList();
        List<Map<String, Object>> editList = new ArrayList();
        List<Map<String, Object>> addMonthList = new ArrayList();
        List<Map<String, Object>> editMonthList = new ArrayList();
        Iterator<Map<String, Object>> itr = list.iterator();
        while (itr.hasNext()) {
            Map<String, Object> map = itr.next();
            if (!map.get("number").toString().equals("0")) {
                if (map.get("summaryId") == null) {
                    addList.add(map);
                } else {
                    editList.add(map);
                }
            } else if (map.get("summaryId") != null) {
                costSummaryMapper.deleteCostSummary(map.get("summaryId").toString());
            }
            if (!map.get("currentNumber").toString().equals("0")) {
                if (map.get("summaryMonthId") == null) {
                    addMonthList.add(map);
                } else {
                    editMonthList.add(map);
                }
            } else if (map.get("summaryMonthId") != null) {
                costSummaryMapper.deleteCostSummaryMonth(map.get("summaryMonthId").toString());
            }
        }
        if (addList.size() > 0) {
            costSummaryMapper.addCostSummary(addList);
        }
        if (editList.size() > 0) {
            costSummaryMapper.editCostSummary(editList);
        }
        if (addMonthList.size() > 0) {
            costSummaryMapper.addCostSummaryMonth(addMonthList);
        }
        if (editMonthList.size() > 0) {
            costSummaryMapper.editCostSummaryMonth(editMonthList);
        }
        return 1;
    }

    @Override
    @Transactional
    public int remove(Map<String, Object> map) {
        int num = costSummaryMapper.deleteCostSummary(map.get("summaryId").toString());
        if (num > 0) {
            num = costSummaryMapper.deleteCostSummaryMonth(map.get("summaryMonthId").toString());
        }
        return num;
    }

    @Override
    public List<Map<String, Object>> addFindCostSummaryAll(Map<String, Object> map) {
        return costSummaryMapper.addFindCostSummaryAll(map);
    }

    @Override
    public int readOnly(Map<String, Object> map) {
        return costSummaryMapper.readOnly(map);
    }

    @Override
    public Map<String, Object> findMaxDate(String companyId, String proId, String buildingId) {
        return costSummaryMapper.findMaxDate(companyId, proId, buildingId);
    }

    @Override
    public List<Map<String, Object>> findDate(Map<String, Object> map) {
        return costSummaryMapper.findDate(map);
    }

    @Override
    @Transactional
    public int copy(Map<String, Object> map) {
        String[] buildingCopyIds = map.get("buildingCopyId").toString().split(",");
        map.put("buildingCopyId", "'" + map.get("buildingCopyId").toString().replaceAll(",", "','") + "'");
        map.put("date", "'" + map.get("date").toString().replaceAll(",", "','") + "'");
        costSummaryMapper.deleteCopySummary(map);
        costSummaryMapper.deleteCopySummaryMonth(map);
        for (String buildingCopyId : buildingCopyIds) {
            map.put("buildingCopyId", buildingCopyId);
            costSummaryMapper.addCopySummary(map);
            costSummaryMapper.addCopySummaryMonth(map);
        }
        return 1;
    }

    @Override
    public List<Map<String, Object>> findCurrentUnivalent(Map<String, Object> map) {
        return costSummaryMapper.findCurrentUnivalent(map);
    }

    @Override
    public AjaxResult exportCurrentUnivalent(Map<String, Object> map) {
        List<Map<String, Object>> list = costSummaryMapper.findCurrentUnivalent(map);
        List<String> colList = new ArrayList<String>();
        colList.add("codeNum");
        colList.add("codeName");
        colList.add("codeUnit");
        colList.add("currentUnivalent");
        List<String> colNameList = new ArrayList<String>();
        colNameList.add("编码编号");
        colNameList.add("编码名称");
        colNameList.add("单位");
        colNameList.add("平均单价");
        return exportData(colNameList, colList, list, "平均单价");
    }

    @Override
    public AjaxResult export(Map<String, Object> map) {
        List<Map<String, Object>> list = costSummaryMapper.exportCost(map);
        List<String> colList = new ArrayList<String>();
        List<String> colNameList = new ArrayList<String>();
        colList.add("codeNum");
        colList.add("codeName");
        colList.add("targetCost");
        colList.add("changeCost");
        colList.add("reviseCost");
        colList.add("changeIncome");
        colList.add("profitChange");
        colList.add("inputTax");
        colList.add("cumulative");
        colList.add("theory");
        colList.add("surplus");
        colList.add("allowance");
        colNameList.add("编码编号");
        colNameList.add("编码名称");
        colNameList.add("目标成本");
        colNameList.add("变动成本");
        colNameList.add("修订成本");
        colNameList.add("变动收入");
        colNameList.add("利润变动");
        colNameList.add("进项税");
        colNameList.add("截止本期累计");
        colNameList.add("截止本期理论");
        colNameList.add("截止本期结余");
        colNameList.add("余量");
        return exportData(colNameList, colList, list, exportFileName(map));
    }

    @Override
    public AjaxResult exportBuilding(Map<String, Object> map) {
        String fileName = exportFileName(map);
        if (map.get("year").equals("") && map.get("month").equals("")) {
            map.put("year", costSummaryMapper.findMaxYear(map));
            map.put("month", costSummaryMapper.findMaxMonth(map));
        } else if (!map.get("year").equals("") && map.get("month").equals("")) {
            map.put("month", costSummaryMapper.findMaxMonth(map));
        }
        List<Map<String, Object>> list = costSummaryMapper.exportBuilding(map);
        List<String> colList = new ArrayList<String>();
        List<String> colNameList = new ArrayList<String>();
        colList.add("codeNum");
        colList.add("codeName");
        colList.add("codeFeature");
        colList.add("number");
        colList.add("containTaxUnivalent");
        colList.add("targetCost");
        colList.add("taxRate");
        colList.add("inputTax");
        colList.add("changeCost");
        colList.add("reviseCost");
        colList.add("changeIncome");
        colList.add("profitChange");
        colList.add("currentNumber");
        colList.add("currentUnivalent");
        colList.add("cumulative");
        colList.add("currentTheoryNumber");
        colList.add("currentTheoryUnivalent");
        colList.add("theory");
        colList.add("surplus");
        colList.add("allowance");
        colNameList.add("编码编号");
        colNameList.add("编码名称");
        colNameList.add("特征");
        colNameList.add("目标数量");
        colNameList.add("目标单价");
        colNameList.add("目标成本");
        colNameList.add("税率");
        colNameList.add("进项税额");
        colNameList.add("变动成本");
        colNameList.add("修订成本");
        colNameList.add("变动收入");
        colNameList.add("利润变动");
        colNameList.add("当期数量");
        colNameList.add("当期单价");
        colNameList.add("截止本期累计");
        colNameList.add("当期理论数量");
        colNameList.add("当期理论单价");
        colNameList.add("截止本期理论");
        colNameList.add("截止本期结余");
        colNameList.add("余量");
        return exportData(colNameList, colList, list, fileName);
    }

    private String exportFileName(Map<String, Object> map) {
        String fileName = map.get("buildingName").equals("") ? "金鹏建设集团" : map.get("proName") + "" + map.get("buildingName");
        String year = map.get("year").equals("") ? "" : map.get("year") + "年";
        String month = map.get("month").equals("") ? "" : map.get("month") + "月";
        return fileName + year + month;
    }

    @Override
    @Transactional
    public int importData(MultipartFile file) {
        String[] colNames = new String[]{"companyId", "proId", "buildingId", "codeNum", "codeFeature", "number", "containTaxUnivalent", "targetCost", "taxRate", "inputTax"};
        List<Map<String, Object>> list = ExcelUtils.getExcelData(file, colNames);
        List<Map<String, Object>> newlist = new ArrayList();
        for (Map<String, Object> map : list) {
            if (proContainsKey(map) && proIsNull(map)) {
                String companyId = paramMapper.getCompanyId(map.get("companyId").toString());
                String proId = projectMapper.getProId(map.get("proId").toString());
                String buildingId = sysParameterMapper.findIdByName(map.get("buildingId").toString(), "楼号");
                String codeNum = costCodeMapper.getCodeId(map.get("codeNum").toString());
                if (StringUtils.isNotEmpty(companyId) && StringUtils.isNotEmpty(proId) && StringUtils.isNotEmpty(buildingId) && StringUtils.isNotEmpty(codeNum)) {
                    map.put("companyId", companyId);
                    map.put("proId", proId);
                    map.put("buildingId", buildingId);
                    map.put("codeNum", codeNum);
                    if (map.get("taxRate").toString().indexOf("%") != -1) {
                        map.put("taxRate", map.get("taxRate").toString().replace("%", ""));
                    }
                    if (Double.valueOf(map.get("taxRate").toString()) < 1) {
                        map.put("taxRate", Double.valueOf(map.get("taxRate").toString()) * 100);
                    }
                    newlist.add(map);
                    costSummaryMapper.deleteImportCostSummary(map);
                }
            }
        }
        if (newlist.size() > 0) {
//            costCodeMapper.updateCodeFeature(newlist);
            int endIndex = 100;
            for (int i = 0; i < newlist.size(); i = endIndex + 1, endIndex += 100) {
                costSummaryMapper.addImportCostSummary(newlist.subList(i, endIndex >= newlist.size() ? newlist.size() : endIndex+1));
            }
        }
        return 1;
    }

    private boolean proContainsKey(Map<String, Object> map) {
        return map.containsKey("companyId") && map.containsKey("proId") && map.containsKey("buildingId") && map.containsKey("codeNum");
    }

    private boolean proIsNull(Map<String, Object> map) {
        return map.get("companyId") != null && map.get("proId") != null && map.get("buildingId") != null && map.get("codeNum") != null;
    }

    @Override
    public AjaxResult importTemplate() {
        List<String> colNameList = new ArrayList<String>();
        colNameList.add("工程公司");
        colNameList.add("项目名称");
        colNameList.add("楼栋号");
        colNameList.add("编码编号");
        colNameList.add("特征");
        colNameList.add("目标数量");
        colNameList.add("目标单价");
        colNameList.add("目标成本");
        colNameList.add("税率");
        colNameList.add("进项税额");
        ExcelUtils.exportData(colNameList, new ArrayList<Map<String, Object>>(), "成本汇总模板");
        return AjaxResult.success("成本汇总模板.xls");
    }

    //导出Excel
    public AjaxResult exportData(List<String> colNameList, List<String> colList, List<Map<String, Object>> DataList, String sheetname) {
        try {
            HSSFWorkbook wkb = new HSSFWorkbook();
            //设置Sheet名称
            HSSFSheet sheet = wkb.createSheet(sheetname);
            //设置样式
            HSSFCellStyle cellStyle = wkb.createCellStyle();
            HSSFFont font = wkb.createFont();
            font.setBold(true);
            cellStyle.setFont(font);
            cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
            //新增一行(用于列名)
            HSSFRow rowFirst = sheet.createRow(0);
            //循环创建列名
            rowFirst.setHeightInPoints(15);
            for (int i = 0; i < colNameList.size(); i++) {
                sheet.setColumnWidth(i, 16 * 256);
                Cell cell = rowFirst.createCell(i);
                cell.setCellValue(colNameList.get(i));
                cell.setCellStyle(cellStyle);
            }
            //设置单元格颜色
            HSSFCellStyle cellStyleFirst = wkb.createCellStyle(), cellStyleSecond = wkb.createCellStyle();
            cellStyleFirst.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            cellStyleFirst.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
            cellStyleSecond.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            cellStyleSecond.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            //将数据放到Excel中
            HSSFRow row;
            for (int i = 1; i <= DataList.size(); i++) {
                //循环写入行
                row = sheet.createRow(i);
                row.setHeightInPoints(15);
                for (int j = 0; j < colList.size(); j++) {
                    Object obj = DataList.get(i - 1).get(colList.get(j));
                    Cell cell = row.createCell(j);
                    if (obj != null && !obj.equals("")) {
                        cell.setCellValue(obj.toString());
                    }
                    if (row.getCell(0).toString().length() == 2 || row.getCell(0).toString().length() == 1) {
                        cell.setCellStyle(cellStyleFirst);
                    } else if (row.getCell(0).toString().length() == 4) {
                        cell.setCellStyle(cellStyleSecond);
                    }
                }
            }
            groupRow(sheet);
            String filePath = Global.getDownloadPath() + sheetname + ".xls";
            FileOutputStream fileOut = new FileOutputStream(filePath);
            wkb.write(fileOut);
            fileOut.close();
            return AjaxResult.success(0);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("失败");
        }
    }

    //动态成本分组
    private void groupRow(HSSFSheet sheet) {
        //获得当前sheet的开始行
        int firstRowNum = sheet.getFirstRowNum() + 1;
        //获得当前sheet的结束行
        int lastRowNum = sheet.getLastRowNum();
        //循环所有行
        List<Integer> firstArr = new ArrayList<>(), second = new ArrayList<>();
        for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
            String firstCol = sheet.getRow(rowNum).getCell(0).toString();
            if (firstCol.length() == 2) {
                firstArr.add(rowNum);
            } else if (firstCol.length() == 4) {
                second.add(rowNum);
            }
        }
        int j = 0;
        for (int i = 0; i < firstArr.size(); i++) {
            Integer num = i == firstArr.size() - 1 ? firstArr.get(i) - 1 : firstArr.get(i + 1) - 1;
            for (; j != second.size(); j++) {
                if (j == second.size() - 1) {
                    sheet.groupRow(second.get(j) + 1, lastRowNum);
                } else {
                    if (num == second.get(j + 1) - 2) {
                        sheet.groupRow(second.get(j) + 1, num);
                        j++;
                        break;
                    } else {
                        sheet.groupRow(second.get(j) + 1, second.get(j + 1) - 1);
                    }
                }
            }
            if (i == firstArr.size() - 1) {
                sheet.groupRow(firstArr.get(i) + 1, lastRowNum);
            } else {
                sheet.groupRow(firstArr.get(i) + 1, firstArr.get(i + 1) - 1);
            }
        }
        sheet.setRowSumsBelow(false);
        sheet.setRowSumsRight(false);
    }
}
